/**
 * Copyright (c) 快宝网络 kuaidihelp.com Co., Ltd. All Rights Reserved 禁止外泄以及用于其它的商业用途
 */

import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { Chart, Geom, Tooltip, Legend, View } from 'bizcharts';
import { isArray, isEqual } from 'lodash';
import DataSet from '@antv/data-set';
import * as turf from '@turf/turf';
import { transformAreaName } from '@/pages/Post/BigScreen/components/_utils';
import styles from './index.less';

const scale = {
  latitude: {
    sync: true,
    nice: false,
  },
  longitude: {
    sync: true,
    nice: false,
  },
};

const colorMap = {
  0: [
    {
      size: '2万以上',
      color: '#ff534f',
      value: [20001],
    },
    {
      size: '1万-2万',
      color: '#FACC14',
      value: [10001, 20000],
    },
    {
      size: '1001-1万',
      color: '#2EC25B',
      value: [1001, 10000],
    },
    {
      size: '1-1000',
      color: '#0078ff',
      value: [1, 1000],
    },
    {
      size: '0',
      color: '#fff',
      value: [0, 1],
    },
  ],
  1: [
    {
      size: '1万以上',
      color: '#ff534f',
      value: [10001],
    },
    {
      size: '5001-1万',
      color: '#FACC14',
      value: [5001, 10000],
    },
    {
      size: '1001-5000',
      color: '#2EC25B',
      value: [1001, 5000],
    },
    {
      size: '1-1000',
      color: '#0078ff',
      value: [1, 1000],
    },
    {
      size: '0',
      color: '#fff',
      value: [0, 1],
    },
  ],
  2: [
    {
      size: '5000以上',
      color: '#ff534f',
      value: [5001],
    },
    {
      size: '1001-5000',
      color: '#FACC14',
      value: [1001, 5000],
    },
    {
      size: '501-1000',
      color: '#2EC25B',
      value: [501, 1000],
    },
    {
      size: '1-500',
      color: '#0078ff',
      value: [1, 500],
    },
    {
      size: '0',
      color: '#fff',
      value: [0, 1],
    },
  ],
  3: [
    {
      size: '500以上',
      color: '#ff534f',
      value: [501],
    },
    {
      size: '101-500',
      color: '#FACC14',
      value: [101, 500],
    },
    {
      size: '51-100',
      color: '#2EC25B',
      value: [51, 100],
    },
    {
      size: '1-50',
      color: '#0078ff',
      value: [1, 50],
    },
    {
      size: '0',
      color: '#fff',
      value: [0, 1],
    },
  ],
};

function keepMapRatio(mapData, c) {
  if (mapData && turf) {
    // 获取数据外接矩形，计算宽高比
    const bbox = turf.bbox(mapData);
    const width = bbox[2] - bbox[0];
    const height = bbox[3] - bbox[1];
    const ratio = height / width;

    const cWidth = c.get('width');
    const cHeight = c.get('height');
    const cRatio = cHeight / cWidth;
    const mapRatio = c.get('mapRatio');
    if (!cRatio || cRatio === mapRatio) return;

    if (cRatio >= ratio) {
      const halfDisRatio = (cRatio - ratio) / 2 / cRatio;
      c.scale('x', {
        range: [0, 1],
      });
      c.scale('y', {
        range: [halfDisRatio, 1 - halfDisRatio],
      });
    } else {
      const halfDisRatio = ((1 / cRatio - 1 / ratio) / 2) * cRatio;
      c.scale('y', {
        range: [0, 1],
      });
      c.scale('x', {
        range: [halfDisRatio, 1 - halfDisRatio],
      });
    }

    c.set('mapRatio', cRatio);
    c.repaint();
  }
}

const getToolLi = data => {
  let str = '';
  const keyMap = {
    num: '今日入库数',
    station_num: '驿站站点数',
    sum_num: '今日到件数量',
    count: '共配中心点数量',
  };
  data.filter(v => !['name', 'abbr_name', 'areaName'].includes(v.name)).forEach(item => {
    str += `<li>${keyMap[item.name]}：${item.value || 0}</li>`;
  });
  return str;
};

const MapChart = ({
  dadaSource = {},
  dataValue = [],
  pointValue = [],
  onClick,
  width,
  level = 0,
  showDot,
  shape,
  dataToolTip,
}) => {
  // 是否是乡镇地区
  const isTown = level == 4;

  const [geo, setGeo] = useState({});

  const processGeoData = (geoData = {}) => {
    const { features = [] } = geoData;
    features.forEach(one => {
      const name = (one && one.properties && one.properties.name) || [];

      // 设置初始值，显示tooltips
      if (level <= 3) {
        one.num = 0;
        one.station_num = 0;
        one.sum_num = 0;
        one.count = 0;
        if (level == 3) {
          one.out_num = 0;
          one.order_num = 0;
          one.sum_num = 0;
        }
      }

      dataValue.forEach(item => {
        const { abbr_name = '', areaName = '', num = 0, station_num = 0, sum_num = 0, count = 0 } =
          item || {};
        transformAreaName(name, abbr_name || areaName, () => {
          one.num = num * 1;
          one.station_num = station_num * 1;
          one.sum_num = sum_num * 1;

          if (level <= 3) {
            one.count = count * 1;
          }
        });
      });
    });

    const geoDv = new DataSet.View().source(geoData, { type: 'GeoJSON' });
    return geoDv;
  };

  useEffect(
    () => {
      if (dadaSource) {
        setGeo(processGeoData(dadaSource));
      }
    },
    [dadaSource],
  );

  return (
    <Chart
      className={styles.chart}
      forceFit
      width={width}
      height={width * 0.77}
      scale={scale}
      onClick={onClick}
      onGetG2Instance={c => {
        keepMapRatio(dadaSource, c, 'render');
        c.on('afterrender', () => {
          keepMapRatio(dadaSource, c, 'rerender');
        });
      }}
    >
      {!isTown && (
        <Legend
          position="bottom-left"
          offsetY={-120}
          offsetX={-60}
          layout="vertical"
          custom
          clickable={false}
          textStyle={{
            textAlign: 'start', // 文本对齐方向，可取值为： start middle end
            fill: 'l(90) 0:#7abefe 1:#3a75ef', // 文本的颜色
            fontSize: '24', // 文本大小
            fontWeight: 'bold', // 文本粗细
            textBaseline: 'middle', // 文本基准线，可取 top middle bottom，默认为middle
          }}
          items={colorMap[level].map(({ size, color }) => ({
            value: size,
            marker: {
              symbol: 'square',
              fill: color,
              radius: 5,
            },
          }))}
        />
      )}
      <View data={geo}>
        <Geom
          type="polygon"
          position="longitude*latitude"
          style={{ lineWidth: 1, stroke: '#505050' }}
          color={
            isTown
              ? '#0078ff'
              : [
                  'sum_num',
                  sum_num => {
                    if (!sum_num) {
                      sum_num = 0;
                    }
                    return colorMap[level]
                      .map(v => {
                        if (sum_num || sum_num == 0) {
                          if (
                            (sum_num >= v.value[0] && sum_num < v.value[1]) ||
                            sum_num >= v.value[0]
                          ) {
                            return v.color;
                          }
                        }
                        return null;
                      })
                      .filter(i => i)[0];
                  },
                ]
          }
          tooltip={dataToolTip}
        />
      </View>

      {showDot &&
        isArray(pointValue) &&
        pointValue.length > 0 && (
          <View data={pointValue}>
            <Geom
              type="point"
              position="longitude*latitude"
              color="#fff"
              shape={shape}
              size={shape == 'circle' ? 7 : 15}
              style={{
                stroke: '#505050',
                lineWidth: 1,
              }}
              tooltip="areaName*station_num*num*sum_num*count"
            />
          </View>
        )}
      <Tooltip
        useHtml
        htmlContent={(_, items) => {
          const { point = {} } = items[0];
          const { _origin = {} } = point;
          const { name, areaName } = _origin;
          const lis = getToolLi(items);
          return `<div class="g2-tooltip" style='position:absolute;'>
                    <div class="g2-tooltip-title" style="color:#fff">${name || areaName}</div>
                    <ul>${lis}</ul>
                  </div>`;
        }}
      />
    </Chart>
  );
};

MapChart.propTypes = {
  width: PropTypes.number.isRequired,
  onClick: PropTypes.func.isRequired,
};

export default React.memo(MapChart, (pervProps, nextProps) =>
  isEqual(pervProps.dadaSource, nextProps.dadaSource),
);
